package main

import (
	"bufio"
	"errors"
	"io"
	"os/exec"
	"sync"
)

var ttydCmd = NewCommandExecutor(`#!/bin/sh
# 检查是否安装了 ttyd
if ! command -v ttyd &> /dev/null; then
    pkg install ttyd -y
fi
SOCK_FILE="/data/data/com.termux/files/home/.termux/ttyd-termux.sock"
TTYD_BIN="/data/data/com.termux/files/usr/bin/ttyd"
if ! pgrep -f "$TTYD_BIN -q -W -i $SOCK_FILE bash" > /dev/null; then
    $TTYD_BIN -q -W -i "$SOCK_FILE" bash &
fi
`)

var alistCmd = NewCommandExecutor(`#!/bin/sh
# 检查是否安装了 alist
if ! command -v alist &> /dev/null; then
    pkg install alist -y
fi
# 启动 alist 服务
alist server
`)

var ddnsgoCmd = NewCommandExecutor(`#!/bin/sh
# 检查是否安装了 ddns-go
if ! command -v ddns-go &> /dev/null; then
    curl -fsSL -o ${HOME}/ddns-go.zip https://gitee.com/atwat/F50-adbPort/releases/download/1.0/ddns-go.zip
    unzip ddns-go.zip
    rm ddns-go.zip
    mv ddns-go /data/data/com.termux/files/usr/bin/
fi
# 启动 ddns-go 服务
ddns-go
`)

func init() {

}

type CommandExecutor struct {
	sh          string
	cmd         *exec.Cmd
	logBuffer   []string
	maxLogLines int
	status      string
	mutex       sync.Mutex
	wg          sync.WaitGroup // 用于等待日志捕获完成
}

func NewCommandExecutor(sh string) *CommandExecutor {
	return &CommandExecutor{
		sh:          sh,
		maxLogLines: 100,
		status:      "stopped",
	}
}

func (e *CommandExecutor) Start() error {
	e.mutex.Lock()
	defer e.mutex.Unlock()

	if e.status == "running" {
		return errors.New("command is already running")
	}

	e.cmd = exec.Command("bash", "-c", e.sh)

	stdout, err := e.cmd.StdoutPipe()
	if err != nil {
		return err
	}

	e.cmd.Stderr = e.cmd.Stdout

	if err := e.cmd.Start(); err != nil {
		return err
	}

	e.status = "running"

	e.wg.Add(1) // 增加等待组计数
	go func() {
		defer e.wg.Done() // 在 goroutine 结束时减少等待组计数
		reader := bufio.NewReader(stdout)
		for {
			line, err := reader.ReadString('\n')
			if err != nil {
				if err != io.EOF {
					printf("读取错误: %v\n", err)
				}
				break
			}

			e.mutex.Lock()
			e.logBuffer = append(e.logBuffer, line)
			if len(e.logBuffer) > e.maxLogLines {
				e.logBuffer = e.logBuffer[len(e.logBuffer)-e.maxLogLines:]
			}
			e.mutex.Unlock()
		}

		// 等待命令执行完成
		e.cmd.Wait()

		e.mutex.Lock()
		e.status = "stopped"
		e.mutex.Unlock()
	}()

	return nil
}

func (e *CommandExecutor) Stop() error {
	e.mutex.Lock()
	defer e.mutex.Unlock()

	if e.status != "running" {
		return errors.New("command is not running")
	}

	if err := e.cmd.Process.Kill(); err != nil {
		return err
	}

	e.status = "stopped"
	return nil
}

func (e *CommandExecutor) GetStatus() string {
	e.mutex.Lock()
	defer e.mutex.Unlock()
	return e.status
}

func (e *CommandExecutor) GetLogs() []string {
	e.mutex.Lock()
	defer e.mutex.Unlock()
	return append([]string(nil), e.logBuffer...)
}

func (e *CommandExecutor) Wait() {
	e.mutex.Lock()
	if e.status != "running" {
		e.mutex.Unlock()
		return
	}
	e.mutex.Unlock()
	e.wg.Wait()
}
